package server

import (
	"strconv"
	"time"

	"github.com/go-kratos/kratos/v2/middleware/logging"
	"github.com/go-kratos/kratos/v2/middleware/ratelimit"
	"github.com/go-kratos/kratos/v2/transport/http"
	"github.com/go-kratos/swagger-api/openapiv2"

	pbButton "gitee.com/danqingzhao/go-dango/api/user/button/v1"
	pbCustomer "gitee.com/danqingzhao/go-dango/api/user/customer/v1"
	pbMenu "gitee.com/danqingzhao/go-dango/api/user/menu/v1"
	pbPermission "gitee.com/danqingzhao/go-dango/api/user/permission/v1"
	pbRole "gitee.com/danqingzhao/go-dango/api/user/role/v1"
	data "gitee.com/danqingzhao/go-dango/apps/user/data"
	service "gitee.com/danqingzhao/go-dango/apps/user/service"
	core "gitee.com/danqingzhao/go-dango/pkg/common/core"
	settings "gitee.com/danqingzhao/go-dango/pkg/proto/settings"
)

// NewHTTPServer new an HTTP server.
func NewHTTPServer(
	c *settings.ServerConf,
	loggers *settings.Loggers,
	logHelpers *settings.LogHelpers,
	permission *service.PermissionService,
	menu *service.MenuService,
	button *service.ButtonService,
	role *service.RoleService,
	customer *service.CustomerService,
	d *data.Data,
) *http.Server {
	var opts = []http.ServerOption{
		http.Middleware(
			core.Recovery(logHelpers.Server),
			ratelimit.Server(),
			logging.Server(loggers.Access),
			core.AuthMiddleware(logHelpers.Server, d.Casbin),
			core.ProtoValidate(),
		),
	}
	addr := c.Http.Host + ":" + strconv.Itoa(int(c.Http.Port))
	opts = append(opts, http.Address(addr))
	timeout := time.Duration(c.Http.Timeout)
	opts = append(opts, http.Timeout(timeout))
	if c.Ssl.SslEnable {
		sslConf, err := settings.LoadSSL(
			c.Ssl.SslDir,
			c.Ssl.SslKeyFile,
			c.Ssl.SslCertFile,
			c.Ssl.SslInsecureSkipVerify,
		)
		if err != nil {
			panic(err)
		}
		opts = append(opts, http.TLSConfig(sslConf))
	}
	srv := http.NewServer(opts...)
	openAPIhandler := openapiv2.NewHandler()
	srv.HandlePrefix("/q/", openAPIhandler)
	pbPermission.RegisterPermissionHTTPServer(srv, permission)
	pbMenu.RegisterMenuHTTPServer(srv, menu)
	pbButton.RegisterButtonHTTPServer(srv, button)
	pbRole.RegisterRoleHTTPServer(srv, role)
	pbCustomer.RegisterCustomerHTTPServer(srv, customer)
	return srv
}
